package com.yunxi.poc.starbucks.service.impl;

import cn.hutool.json.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunxi.poc.starbucks.common.BizConstant;
import com.yunxi.poc.starbucks.entity.TOrderNew;
import com.yunxi.poc.starbucks.entity.TOrderNewDetails;
import com.yunxi.poc.starbucks.mapper.TOrderNewDetailsMapper;
import com.yunxi.poc.starbucks.service.ITOrderNewDetailsService;
import com.yunxi.poc.starbucks.service.ITOrderNewService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author shiyuan.xlc
 * @since 2021-08-25
 */
@Service
public class TOrderNewDetailsServiceImpl extends ServiceImpl<TOrderNewDetailsMapper, TOrderNewDetails> implements ITOrderNewDetailsService {

    private final static Logger logger = LoggerFactory.getLogger(BuyServiceImpl.class);

    @Resource
    ITOrderNewService orderNewService;

    @Resource
    ThreadPoolTaskExecutor executorService;

    @Override
    public void batchGenDetails() {
        long size = BizConstant.BATCH_NUM, currentPage = 0, total;

        QueryWrapper<TOrderNew> condWrapper = new QueryWrapper<>();
        condWrapper.select("id", "trace");
        condWrapper.eq("cal_status", "SUCCESS");
        condWrapper.orderByAsc("id");
        condWrapper.in("id", Arrays.asList("72057596499415578", "72057596499344763"));

        Page<TOrderNew> pageOrders = this.orderNewService.page(new Page<>(++currentPage, size, true), condWrapper);

        total = pageOrders.getTotal();
        if (total == 0) return;

        logger.info("Task running ->" + " total: " + total);

        while (pageOrders.getRecords().size() > 0) {
            List<TOrderNew> orderNews = pageOrders.getRecords();

            executorService.execute(() -> {
                batchGenDetails(orderNews);
                logger.info("Task count: " + executorService.getThreadPoolExecutor().getTaskCount()
                        + " Task active count: " + (executorService.getActiveCount() - 1)
                        + " Task completed count: " + (executorService.getThreadPoolExecutor().getCompletedTaskCount() + 1)
                        + " Task ending at: " + LocalDateTime.now());
            });

            pageOrders = this.orderNewService.page(new Page<>(++currentPage, size, false), condWrapper);
        }

    }

    @Override
    public void batchGenDetails(List<TOrderNew> orderNews) {
        List<TOrderNewDetails> orderNewDetailsList = Collections.synchronizedList(new ArrayList<>());
        orderNews.parallelStream().forEach((on) -> {
            List<TOrderNewDetails> traces = new JSONArray(on.getTrace()).toList(TOrderNewDetails.class);
            if (traces.size() > 0) {
                traces.forEach(t -> {
                    t.setId(on.getId());
                    if (StringUtils.hasLength(on.getStoreId()) && on.getStoreId().equals(t.getGlobalStoreNumber()))
                        t.setSameAsOrg("1");
                    if (StringUtils.hasLength(on.getNewId()) && on.getNewId().equals(t.getGlobalStoreNumber()))
                        t.setSelected("1");
                });
                orderNewDetailsList.addAll(traces);
            }
        });
        if (orderNewDetailsList.size() > 0) this.saveBatch(orderNewDetailsList);
    }

}
